package com.xafc.demo.sys.service.impl;


import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.CaseFormat;
import com.xafc.demo.sys.dao.RoleMapper;
import com.xafc.demo.sys.model.dto.RoleDto;
import com.xafc.demo.sys.model.entity.Menu;
import com.xafc.demo.sys.model.entity.Role;
import com.xafc.demo.sys.model.entity.RoleMenu;
import com.xafc.demo.framework.result.ResultCode;
import com.xafc.demo.sys.model.query.RolePageQuery;
import com.xafc.demo.sys.service.IRoleMenuService;
import com.xafc.demo.sys.service.IRoleService;
import com.xafc.demo.security.utils.UserHolderUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    private IRoleMenuService roleMenuService;

    @Override
    public Page<RoleDto> getRoleList(RolePageQuery query) {
        // 设置分页
        final Page<RoleDto> page = new Page<>(query.getPage(), query.getLimit());
        // 设置排序
        if(StrUtil.isNotEmpty(query.getOrder())){
            // 驼峰转换
            String field = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, query.getField());
            String order = query.getOrder();
            page.setOrders(
                    ListUtil.toList(
                            StrUtil.equals("asc", order) ? OrderItem.asc(field) : OrderItem.desc(field)
                    ));
        }else {
            // 默认排序
            page.setOrders(ListUtil.toList(OrderItem.desc("id")));
        }

        List<RoleDto> RoleDtoList = baseMapper.selectRoleList(page, query);
        page.setRecords(RoleDtoList);
        return page;
    }

    @Override
    public Role getRoleById(Integer id) {
        return baseMapper.selectById(id);
    }

    @Override
    public List<Role> getRoleByIds(List<Integer> ids) {
//        return baseMapper.selectBatchIds(ids);
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.select("id", "name").in("id", ids);
        return baseMapper.selectList(wrapper);
    }

    @Override
    public ResultCode addRole(Role role) {
        ResultCode resultCode;
        Integer count = baseMapper.selectCount(new QueryWrapper<Role>().eq("name", role.getName()));
        if (count > 0){
            resultCode = ResultCode.fail("角色已存在");
        }else {
            if(role.getStatus() == null)  role.setStatus(1);
            role.setCreateTime(new Date());
            role.setCreator(UserHolderUtils.getUserId());

            int num= baseMapper.insert(role);
            //新增成功
            if (num>0){
                resultCode = ResultCode.success("新增成功");
            }else {
                resultCode = ResultCode.error( "新增失败");
            }
        }
        return resultCode;
    }

    @Override
    public ResultCode updateRole(Role role) {
        ResultCode resultCode;
        Integer count = baseMapper.selectCount(new QueryWrapper<Role>().eq("id", role.getId()));
        if(count > 0){
            role.setUpdateTime(new Date());
            role.setUpdater(UserHolderUtils.getUserId());
            int num = baseMapper.updateById(role);
            if(num>0){
                resultCode = ResultCode.success("更新成功");
            }else {
                resultCode = ResultCode.error("更新失败");
            }
        }else {
            resultCode = ResultCode.fail("无效的角色");
        }
        return resultCode;
    }

    @Override
    public ResultCode deleteRole(Integer id) {
        ResultCode resultCode;
        Integer count = baseMapper.selectCount(new QueryWrapper<Role>().eq("id", id));
        if(count > 0){
            int num = baseMapper.deleteById(id);
            if(num>0){
                resultCode = ResultCode.success("删除成功");
            }else {
                resultCode = ResultCode.error("删除失败");
            }
        }else {
            resultCode = ResultCode.fail("无效的角色");
        }
        return resultCode;
    }

    @Override
    public ResultCode discardRole(Integer id) {
        ResultCode resultCode;
        Integer count = baseMapper.selectCount(new QueryWrapper<Role>().eq("id", id));
        if(count > 0){
            UpdateWrapper<Role> wrapper = new UpdateWrapper<>();
            wrapper.eq("id", id).set("status", 0);
            int num = baseMapper.update(null, wrapper);
            if(num>0){
                resultCode = ResultCode.success("废弃成功");
            }else {
                resultCode = ResultCode.error("废弃失败");
            }
        }else {
            resultCode = ResultCode.fail("无效的角色");
        }
        return resultCode;
    }

    @Override
    public ResultCode grantPermission(Integer roleId, List<Integer> menuIds) {
        ResultCode resultCode;
        // 1、批量删除RoleMenu，删除roleId对应的全部menuIds
        roleMenuService.remove(new QueryWrapper<RoleMenu>().eq("role", roleId));

        // 2、批量添加RoleMenu，增加roleId对应的全部menuIds
        List<RoleMenu> roleMenuList = new ArrayList<>();
        menuIds.forEach(id -> {
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setMenu(id);
            roleMenu.setRole(roleId);
            roleMenu.setCreateTime(new Date());
//            roleMenu.setCreator(userId);
            roleMenuList.add(roleMenu);
        });
        if (roleMenuList.size()>0){
            roleMenuService.saveBatch(roleMenuList);
        }

        // 3、返回
        resultCode = ResultCode.success("授权成功");
        return resultCode;
    }

    @Override
    public List<Menu> getPermission(Integer roleId) {
        List<RoleMenu> roleMenuList = roleMenuService.list(new QueryWrapper<RoleMenu>().eq("role", roleId));
        List<Menu> menuList = new ArrayList<>();
        roleMenuList.forEach(o -> {
            Menu menu = new Menu();
            menu.setId(o.getMenu());
            menuList.add(menu);
        });
        return menuList;
    }
}
